package service

import (
	"log"

	nexport "nggs/export"
)

type Producer = func() nexport.IService

type factory struct {
	name     string
	producer Producer
}

func newMessageFactory(name string, producer Producer) *factory {
	return &factory{
		name:     name,
		producer: producer,
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
type FactoryManager struct {
	factories map[string]*factory
}

func NewFactoryManager() *FactoryManager {
	m := &FactoryManager{
		factories: map[string]*factory{},
	}
	return m
}

func (mgr *FactoryManager) MustRegister(name string, producer Producer) {
	if producer == nil {
		log.Panicf("register service factory fail, %s, name=%s", ErrProducerIsNil.Error(), name)
	}

	if f, ok := mgr.factories[name]; ok {
		log.Panicf("register service factory fail, %s, name=%s, factory=%+v", ErrDuplicateFactory.Error(), name, f)
	}

	mgr.factories[name] = newMessageFactory(name, producer)
}

func (mgr *FactoryManager) Produce(name string) (nexport.IService, error) {
	if factory := mgr.factories[name]; factory != nil {
		return factory.producer(), nil
	}
	return nil, ErrUnsupportedService
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var FM = NewFactoryManager()
